
#include "LCD1602.h"
#include "Delay.h"
#include <REGX52.H>
#include <math.h>
#include <stdarg.h>

// 引脚配置：
sbit LCD_RS = P2 ^ 6;
sbit LCD_RW = P2 ^ 5;
sbit LCD_EN = P2 ^ 7;

/**
 * @brief  LCD1602写入命令
 * @param  cmd 八位二进制命令
 * @retval 无
 */
void cmd(char cmd) {
  LCD_RS = 0;
  LCD_RW = 0;
  LCD_DataPort = cmd;
  LCD_EN = 1;
  Delay(1);
  LCD_EN = 0;
  Delay(1);
}
/**
 * @brief  LCD1602写入数据到DDRAM
 * @param  dat	想显示的字符
 * @retval 无
 */
void putchar(char dat) {
  LCD_RS = 1;
  LCD_RW = 0;
  LCD_DataPort = dat;
  LCD_EN = 1;
  Delay(1);
  LCD_EN = 0;
  Delay(1);
}
/**
 * @brief  LCD1602初始化
 * @param  无
 * @retval 无
 */
void init(void) {
  cmd(0x3c); // 八位数据接口，两行显示，5*10点阵
  cmd(0x0f); // 显示开，光标开，闪烁开
  cmd(0x06); // 数据读写操作后，光标自动加一，画面不动
  cmd(0x01); // 光标复位，清屏
}
/**
 * @brief  LCD1602读取光标位置
 * @param  无
 * @retval 8位DDRAM地址值
 */
char getcur(void) {
  char cur;
  LCD_RS = 0;
  LCD_RW = 1;
  LCD_EN = 1;
  cur = LCD_DataPort; // 不作忙检测，因为c51太慢了
  LCD_EN = 0;
  return cur;
}
/**
 * @brief  LCD1602设置光标位置
 * @param  cur 8位光标地址
 * @retval 无
 */
void setcur(char cur) { cmd(0x80 | cur); }

/**
 * @brief  LCD1602格式化字符串输出简陋实现，无转义字符，变量均假设为8位
 * @param  *String 字符串头指针
 * @retval 无
 */
void printf(const char *String, ...) {
  unsigned char i;
  va_list ap;
  va_start(ap, String);
  for (i = 0; String[i] != '\0'; i++) {
    if (String[i] != '%')
      putchar(String[i]);
    else {
      i++;
      switch (String[i]) {
      case 'd': {
        char j;
        char out[9];
        char value = va_arg(ap, char);
        if (value == 0) {
          putchar('0');
          break;
        }
        if (value < 0)
          putchar('-');
        value = abs(value);
        for (j = 0; value != 0; ++j) {
          out[j] = value % 10;
          value /= 10;
        }
        for (--j; j > -1; --j)
          putchar(out[j] + '0');
        break;
      }
      case 's': {
        char j;
        char *str = va_arg(ap, char *);
        for (j = 0; str[j] != '\0'; j++)
          putchar(str[j]);
        break;
      }
      case 'c': {
        char a = va_arg(ap, char);
        putchar(a);
        break;
      }
      }
    }
  }
  va_end(ap);
}
